#include<iostream>
#include<string>
#include<vector>
#include <sys/types.h>
#include <unistd.h>
#include"task.hpp"
#include <sys/wait.h>
using namespace std;
class channel
{
	public:
          channel(int wfd,pid_t id,const string&name)
		  :_wfd(wfd)
		   ,_subprocessid(id)
		   ,_name(name)
		 {
		 }
         void closechannel()
	 {close(_wfd);}
	 void wait()
	 {
	 pid_t rid=waitpid(_subprocessid,nullptr,0);
	 if(rid>0)
	 {
	 cout<<"wait"<<rid<<"sussess"<<endl;
	 
	 }
	 
	 
	 
	 }
         ~channel()
                {}

         int getwfd()
	 {return _wfd;}

	 pid_t getprocessid()
	 {return _subprocessid;}

	 string getname()
	 {return _name;}
        private:
	int _wfd;
	pid_t _subprocessid;
	string _name;
};
int whichone(int channelnum)
{
static int count=0;
int channel=count;
count++;
count%=channelnum;
return channel;
}
void sendtasknum(channel& chan,int taskcommand)
{

write(chan.getwfd(),&taskcommand,sizeof(taskcommand));
}

void task(int index)
{
while(true)
     {
      
      int command=0;
      int n=read(index,&command,sizeof(command));
      if(n==sizeof(int))
        {
	cout<<"pid is:"<<getpid()<<"handle task"<<endl;
          runtask(command);
	}  
      else if(n==0)
	 {
	 cout<<"sub process:"<<getpid()<<"quit!!"<<endl;
	 break;
	 }
    }
}
void cleanchannels(vector<channel>& channels)
{
for(auto &channel:channels)
{
channel.closechannel();

channel.wait();
}
//for(auto &channel:channels)
//{
//channel.wait();

//}





}




int main(int argc,char *argv[])
{
//第一步:创建子进程和管道
if(argc!=2)
	{
	cout<<"usage:"<<argv[0]<<"processnum"<<endl;
	}
int num=stoi(argv[1]);


loadtask();
vector<channel>channels;
for(int i=0;i<num;i++)
   {
   int pipefd[2]={0};
   int n=pipe(pipefd);
   if(n<0)
	   exit(1);
   pid_t id=fork();

   if(id==0)
   {
   close(pipefd[1]);
    task(pipefd[0]);//第五步
   close(pipefd[0]);
   exit(0);
   }
   string  channel_name="channel-"+to_string(i);
   close(pipefd[0]);
   channels.push_back(channel(pipefd[1],id,channel_name));
   }
//while(true)
//{	
sleep(1);
//第二步:选择任务
  int taskcommand=slecttask();
//第三步：选择哪一个子进程来执行对应任务
  int channel_id=whichone(num);
//第四步：向第三步选择的管道发送第二步选择的函数指针数组下标
  sendtasknum(channels[channel_id],taskcommand);
//第六步回收
//}
  cleanchannels(channels);


 
}
